


fn generate_set() -> Box<Set> {
    let mut set = set_new(string_hash, string_equal);
    let mut buf: [i8; 10] = [0; 10];
    for i in 0..10000 {
        let cstr = CString::new(i.to_string()).unwrap();
        unsafe {
            ptr::copy_nonoverlapping(cstr.as_ptr(), buf.as_mut_ptr(), cstr.as_bytes().len());
            let value = libc::strdup(buf.as_ptr());
            set_insert(&mut *set, value);
            assert!(set_num_entries(&*set) == i + 1);
        }
    }
    set_register_free_function(&mut *set, libc::free);
    set
}


  // 'rust
  println!("Hello, world!");
  fn main() {
use std::alloc::{alloc, dealloc, Layout};
use libc::{malloc, free};

extern "C" {
    fn int_hash(v: *const i32) -> u64;
    fn int_equal(a: *const i32, b: *const i32) -> bool;
    fn alloc_test_set_limit(lim: usize);
    fn alloc_test_get_allocated() -> usize;
}

#[derive(Default)]
struct Set {
    hashmap: HashSet<Box<i32>>,
}

impl Set {
    fn new(hash_func: fn(*const i32) -> u64, equal_func: fn(*const i32, *const i32) -> bool) -> *mut Set {
        Box::into_raw(Box::new(Set {
            hashmap: HashSet::default(),
        }))
    }

    fn register_free_function(&mut self, _free_func: unsafe extern "C" fn(*mut libc::c_void)) {
        // In Rust, `drop` takes care of freeing memory, no need to register a free function.
    }

    fn insert(&mut self, value: Box<i32>) {
        self.hashmap.insert(value);
    }

    fn free(ptr: *mut Set) {
        unsafe {
            Box::from_raw(ptr);
        }
    }
}

extern "C" fn free_func(ptr: *mut libc::c_void) {
    unsafe {
        free(ptr);
    }
}

#[no_mangle]
pub extern "C" fn test_set_new_free() {
    let mut set: *mut Set;
    let mut i: i32;
    let mut value: *mut i32;

    // Allocate a new set
    set = Set::new(int_hash, int_equal);
    assert!(!set.is_null());

    unsafe {
        (*set).register_free_function(free_func as unsafe extern "C" fn(*mut libc::c_void));
    }

    // Fill the set with values before freeing
    for i in 0..10000 {
        unsafe {
            value = malloc(std::mem::size_of::<i32>()) as *mut i32;
            if !value.is_null() {
                *value = i;
                (*set).insert(Box::from_raw(value));
            }
        }
    }

    // Free the set
    Set::free(set);

    // Test out of memory scenario
    unsafe {
        alloc_test_set_limit(0);
        set = Set::new(int_hash, int_equal);
        assert!(set.is_null());

        alloc_test_set_limit(1);
        set = Set::new(int_hash, int_equal);
        assert!(set.is_null());
        assert!(alloc_test_get_allocated() == 0);
    }
}
```fn test_set_insert() {
    let numbers1 = [1, 2, 3, 4, 5, 6];
    let numbers2 = [5, 6, 7, 8, 9, 10];
    let mut set = Set::new(int_hash, int_equal);
    for &num in &numbers1 {
        set.insert(num);
    }
    for &num in &numbers2 {
        set.insert(num);
    }
    assert!(set.num_entries() == 10);
}

 use std::fmt::Write;
 
 fn main() {
     println!("Start");
     for i in 0..10000 {
         println!("{}", i );
     }
     println!("Done");
 
     let mut sum = 0;
     for i in 0..100 {
         sum += i;
     }
     println!("Sum: {}", sum);
#[repr(C)]
fn test_set_remove() {
    unsafe {
        let set = generate_set();
        assert!(!set.is_null());
        let mut buf = [0u8; 10];
        let mut num_entries = set_num_entries(set);
        assert_eq!(num_entries, 10000);
        for i in 4000..6000 {
            let s = CString::new(i.to_string()).unwrap();
            ptr::copy_nonoverlapping(
                s.as_ptr(),
                buf.as_mut_ptr() as *mut c_char,
                s.to_bytes().len() + 1,
            );
            assert!(set_query(set, buf.as_ptr() as *const c_char) != 0);
            assert!(set_remove(set, buf.as_ptr() as *const c_char) != 0);
            assert_eq!(set_num_entries(set), num_entries - 1);
            assert_eq!(set_query(set, buf.as_ptr() as *const c_char), 0);
            num_entries -= 1;
        }
        for i in -1000..-500 {
            let s = CString::new(i.to_string()).unwrap();
            ptr::copy_nonoverlapping(
                s.as_ptr(),
                buf.as_mut_ptr() as *mut c_char,
                s.to_bytes().len() + 1,
            );
            assert!(set_remove(set, buf.as_ptr() as *const c_char) == 0);
            assert_eq!(set_num_entries(set), num_entries);
        }
        for i in 50000..51000 {
            let s = CString::new(i.to_string()).unwrap();
            ptr::copy_nonoverlapping(
                s.as_ptr(),
                buf.as_mut_ptr() as *mut c_char,
                s.to_bytes().len() + 1,
            );
            assert!(set_remove(set, buf.as_ptr() as *const c_char) == 0);
            assert_eq!(set_num_entries(set), num_entries);
        }
        set_free(set);
    }
}

fn test_set_union() {
    let numbers1 = vec![1, 2, 3, 4, 5, 6, 7];
    let numbers2 = vec![5, 6, 7, 8, 9, 10, 11];
    let result = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
    let set1 = set_new(int_hash, int_equal);
    for n in &numbers1 {
        set_insert(set1, n);
    }
    let set2 = set_new(int_hash, int_equal);
    for n in &numbers2 {
        set_insert(set2, n);
    }
    let result_set = set_union(set1, set2);
    assert!(set_num_entries(result_set) == 11);
    for r in &result {
        assert!(set_query(result_set, r) != 0);
    }
    set_free(result_set);
    alloc_test_set_limit(0);
    assert!(set_union(set1, set2).is_none());
    alloc_test_set_limit(2 + 2);
    let allocated = alloc_test_get_allocated();
    assert!(set_union(set1, set2).is_none());
    assert!(alloc_test_get_allocated() == allocated);
    alloc_test_set_limit(2 + 7 + 2);
    let allocated = alloc_test_get_allocated();
    assert!(set_union(set1, set2).is_none());
    assert!(alloc_test_get_allocated() == allocated);
    set_free(set1);
    set_free(set2);
}

fn test_set_intersection() {
    let numbers1 = vec![1, 2, 3, 4, 5, 6, 7];
    let numbers2 = vec![5, 6, 7, 8, 9, 10, 11];
    let result = vec![5, 6, 7];
    let mut set1 = Set::new(int_hash, int_equal);
    let mut set2 = Set::new(int_hash, int_equal);
    let mut result_set;
    for num in &numbers1 {
        set1.insert(num);
    }
    for num in &numbers2 {
        set2.insert(num);
    }
    result_set = set_intersection(&set1, &set2);
    assert!(result_set.num_entries() == 3);
    for res in &result {
        assert!(result_set.query(res));
    }
    alloc_test_set_limit(0);
    assert!(set_intersection(&set1, &set2).is_none());
    alloc_test_set_limit(2 + 2);
    let allocated = alloc_test_get_allocated();
    assert!(set_intersection(&set1, &set2).is_none());
    assert!(alloc_test_get_allocated() == allocated);
    set1.free();
    set2.free();
    result_set.free();
}

fn test_set_to_array() {
    let mut set = Set::new();
    let mut values = [0; 100];
    let mut array: Vec<*mut c_void>;
    let mut i: usize = 0;
    for i in 0..100 {
        values[i] = 1;
        set.insert(values.as_mut_ptr().offset(i as isize) as *mut c_void);
    }
    array = set.to_array();
    for i in 0..100 {
        assert_eq!(*(array[i] as *mut i32), 1);
        *(array[i] as *mut i32) = 0;
    }
    alloc_test_set_limit(0);
    assert!(set.to_array().is_empty());
    set.free();
}

fn test_set_iterating() {
    let mut set: *mut Set;
    let mut iterator: SetIterator = SetIterator;
    let mut count: i32;
    set = generate_set();
    count = 0;
    set_iterate(set, &mut iterator);
    while set_iter_has_more(&mut iterator) != 0 {
        set_iter_next(&mut iterator);
         count += 1;
     }
     assert!(set_iter_next(&mut iterator).is_null());
     assert!(count == 10000);
    set_free(set);
    set = set_new(int_hash, int_equal);
     set_iterate(set, &mut iterator);
     assert!(set_iter_has_more(&mut iterator) == 0);
     set_free(set);
}

#[repr(C)]
#[repr(C)]
fn test_set_iterating_remove() {
    let mut set: *mut Set;
    let mut iterator = SetIterator;
    let mut count: i32;
    let mut removed: u32;
    let mut value: *mut c_char;
    set = generate_set();
    count = 0;
    removed = 0;
    set_iterate(set, &mut iterator);
    while set_iter_has_more(&iterator) {
        value = set_iter_next(&mut iterator);
        if libc::atoi(value) % 100 == 0 {
            set_remove(set, value);
            removed += 1;
        }
        count += 1;
    }
    assert!(count == 10000);
    assert!(removed == 100);
    assert!(set_num_entries(set) == 10000 - removed);
    set_free(set);
}

fn new_value(value: i32) -> *mut i32 {
    unsafe {
        let result = libc::malloc(std::mem::size_of::<i32>()) as *mut i32;
        if !result.is_null() {
            ptr::write(result, value);
            ALLOCATED_VALUES.fetch_add(1, Ordering::SeqCst);
        }
        result
    }
}

fn free_value(value: *mut std::ffi::c_void) {
    unsafe {
        libc::free(value);
        ALLOCATED_VALUES -= 1;
    }
}

fn test_set_free_function() {
    let mut set = Set::new(int_hash, int_equal);
    set.register_free_function(free_value);
    ALLOCATED_VALUES.with(|val| {
        *val.borrow_mut() = 0;
    });
    for i in 0..1000 {
        let value = new_value(i);
        set.insert(value);
    }
    ALLOCATED_VALUES.with(|val| {
        assert_eq!(*val.borrow(), 1000);
    });
    let i = 500;
    set.remove(&i);
    ALLOCATED_VALUES.with(|val| {
        assert_eq!(*val.borrow(), 999);
    });
    set.free();
    ALLOCATED_VALUES.with(|val| {
        assert_eq!(*val.borrow(), 0);
    });
}

fn test_set_out_of_memory() {
    let mut set;
    let mut values = vec![0; 66];
    unsafe {
        set = set_new(int_hash, int_equal);
        alloc_test_set_limit(0);
        values[0] = 0;
        assert!(set_insert(set, &values[0]) == 0);
        assert!(set_num_entries(set) == 0);
        alloc_test_set_limit(-1);
        for i in 0..65 {
            values[i] = i as i32;
            assert!(set_insert(set, &values[i]) != 0);
            assert!(set_num_entries(set) == (i + 1) as u32);
        }
        assert!(set_num_entries(set) == 65);
        alloc_test_set_limit(0);
        values[65] = 65;
        assert!(set_insert(set, &values[65]) == 0);
        assert!(set_num_entries(set) == 65);
        set_free(set);
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let tests: Vec<fn()> = vec![];
    run_tests(&tests);
    unsafe {
        println!("num_assert: {}", NUM_ASSERT);
    }
}

